package com.humanminoritygame.web;

import java.io.IOException;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.humanminoritygame.common.Utils;
import com.humanminoritygame.model.AnswerType;
import com.humanminoritygame.model.CategoryRepo;
import com.humanminoritygame.model.QuestionRepo;
import com.humanminoritygame.model.Room;
import com.humanminoritygame.model.RoomRepo;
import com.humanminoritygame.model.Round;
import com.humanminoritygame.model.Subscription;
import com.humanminoritygame.model.SubscriptionRepo;
import com.humanminoritygame.model.User;
import com.humanminoritygame.model.UserRepo;
import com.humanminoritygame.model.UserRoundResult;
import com.humanminoritygame.model.UserRoundResultRepo;

@Controller
public class RoomController {

  SubscriptionRepo subscriptions;
  QuestionRepo questions;
  CategoryRepo categories;
  UserRepo users;
  UserRoundResultRepo userRoundResults;
  RoomRepo rooms;
  
  @Autowired
  public RoomController(SubscriptionRepo subscriptions, QuestionRepo questions, CategoryRepo categories, UserRepo users, UserRoundResultRepo userRoundResults, RoomRepo rooms){
    this.users = users;
    this.subscriptions = subscriptions;
    this.questions = questions;
    this.categories = categories;
    this.userRoundResults = userRoundResults;
    this.rooms = rooms;
  }

  @RequestMapping(method = RequestMethod.GET)
  public ModelAndView history(HttpSession session, @RequestParam("id") Long roomId, @RequestParam("error") int error){
    ModelAndView mav = new ModelAndView();
    mav.setViewName("roomHistory");
    User user = (User)session.getAttribute("user");
    Room room = rooms.getRoomById(roomId);
    Subscription subscription = subscriptions.getSubscription(user, room);
    try{
      if(room.isClosed()){
        return historyClosed(session, roomId);
      }
      if(error == 1 ){
        throw new Exception("You have already voted during the last round. Please wait.");
      }
    }catch(Exception e){
      mav.addObject("hasError", true);
      mav.addObject("error", e.getMessage());
      //throw new RuntimeException(e);
    }finally{
      mav.addObject("subscription", subscription);
      mav.addObject("userRanking", userRoundResults.getRanking(subscription));
      mav.addObject("totalPoints", subscription.getScore());
      mav.addObject("question", subscription.getQuestion());
      
      long seconds = room.getLastRound().getDueDate().getMillis() - new DateTime().getMillis();////////////////////////////////////
      seconds /= 1000;
      if(seconds<0){
        seconds = 0;
      }
      mav.addObject("timeremaining", seconds);
      mav.addObject("totaltime", room.getCategory().getFrequency());
      Round round = room.getLastRound();
      if(userRoundResults.hasVoted(subscription, round)){
        mav.addObject("disabled", "disabled");
        UserRoundResult urr = userRoundResults.getUserRoundResult(round, subscription);
        if(urr.getAnswer().equals(AnswerType.A)){
          mav.addObject("selectedA", "checked");
        }else if(urr.getAnswer().equals(AnswerType.B)){
          mav.addObject("selectedB", "checked");
        }
      }else{
        mav.addObject("disabled", "");
        mav.addObject("selectedA", "checked");
      }
      
    }
    return mav;
  }

  @RequestMapping(method = RequestMethod.GET)
  public void lastRoundInfo(HttpServletRequest request, HttpServletResponse response, @RequestParam("id") Long roomId, @RequestParam("error") int error, @RequestParam("qid") Long qId, @RequestParam("uid") Long uid, @RequestParam("image") Double number){
    String xml = new String("<?xml version='1.0' encoding='ISO-8859-1'?>");
    response.setContentType("text/xml");
    AnswerType answer = rooms.getLastRoomResult(roomId);
    Room laroom = rooms.getRoomById(roomId);
    Subscription subs = subscriptions.getSubscription(users.getUserById(uid), laroom);

    xml= xml + "<roundinfo><lastResult>";
    if(answer == null){
      xml = xml + Utils.writeXMLAttribute("NN.gif", "image");
      xml = xml + Utils.writeXMLAttribute("No Answer", "answer");
    } else if(answer==AnswerType.A){
      xml = xml + Utils.writeXMLAttribute("A" + qId + ".png", "image");
      xml = xml + Utils.writeXMLAttribute(subs.getQuestion().getAnswerA(), "answer");
    } else {
      xml = xml + Utils.writeXMLAttribute("B" + qId + ".png", "image");
      xml = xml + Utils.writeXMLAttribute(subs.getQuestion().getAnswerB(), "answer");
    }
    xml = xml + "</lastResult>";

    xml = xml + "<ranking>" + userRoundResults.getRanking(subs) + "</ranking>";

    xml = xml + "<points>" + subs.getScore() + "</points>";

    xml = xml + "<time>" + (laroom.getLastRound().getRemainingTime()/1000) + "</time>";
    xml = xml + "<roomtime>" + (laroom.getRemainingTime()) + "</roomtime>";
    xml = xml + "</roundinfo>";
    //System.out.println(xml);
    try {
      ServletOutputStream out = response.getOutputStream();
      out.write(xml.getBytes());
      out.flush();
      out.close();
    } catch (IOException e) {
      throw new RuntimeException();
    }
  }

  @RequestMapping(method = RequestMethod.GET)
  public void addVote(HttpServletRequest request, HttpServletResponse response,@RequestParam("subscription") Long subscriptionId, 
      @RequestParam("answer") String answerChar){
    String xml = new String("<?xml version='1.0' encoding='ISO-8859-1'?>");
    response.setContentType("text/xml");
    Subscription subscription = subscriptions.getSubscription(subscriptionId);
    AnswerType answer;
    if(answerChar.equals("A")){
      answer = AnswerType.A;
    }else if(answerChar.equals("B")){
      answer = AnswerType.B;
    }else{
      throw new RuntimeException("No Valid Answer has arrived by POST");
    }
    int error = 0;
    Room room = subscription.getRoom();
    Round round = room.getLastRound();
    if(userRoundResults.hasVoted(subscription, round)){
      error = 1;
      //error = "You have already voted during the last round. Please wait."
    }else{
      UserRoundResult userRoundResult = new UserRoundResult(answer, subscription, round);
      userRoundResults.addUserRoundResult(userRoundResult);
    }
  //  return "redirect:history?id="+subscription.getRoom().getId()+"&error="+error;
    
    if(error == 0){
      xml = xml + Utils.writeXMLAttribute("0", "response");
    }else{
      xml = xml + Utils.writeXMLAttribute("1", "response");
    }
    try {
      ServletOutputStream out = response.getOutputStream();
      out.write(xml.getBytes());
      out.flush();
      out.close();
    } catch (IOException e) {
      throw new RuntimeException();
    }
    
  }
  
  
  @RequestMapping(method = RequestMethod.GET)
  public ModelAndView historyClosed(HttpSession session, @RequestParam("id") Long roomId){
    ModelAndView mav = new ModelAndView();
    mav.setViewName("roomHistoryClosed");
    User user = (User)session.getAttribute("user");
    Room room = rooms.getRoomById(roomId);
    Subscription subscription = subscriptions.getSubscription(user, room);
    mav.addObject("subscription", subscription);
    mav.addObject("userRanking", userRoundResults.getRanking(subscription));
    mav.addObject("totalPoints", subscription.getScore());
    mav.addObject("question", subscription.getQuestion());
    String summaries = new String("[0, 0], ");
    String votes = new String("[0, 0], ");
    int i=1;
    int vote = 0;
    for(Round r : room.getRounds()){
      if(r.hasElapsed() && r.getSummary() != null){
        summaries += "[" + i + ", " + r.getSummary().getAnswerValue() + "], ";
        UserRoundResult urr = userRoundResults.getUserRoundResult(r, subscription);
        if(urr != null){
          vote = urr.getRoundAcumulatedPoints();
        }
        votes += "[" + i + ", " + vote + "], ";
        i++;
      }
    }
    if(summaries.length()>0){
      //le saca la coma y el espacio del final
      summaries = summaries.substring(0, summaries.length()-2);
      votes = votes.substring(0, votes.length()-2);
    }
    mav.addObject("summaries", summaries);
    mav.addObject("votes", votes);
    return mav;
  }
  
  @RequestMapping(method = RequestMethod.GET)
  public ModelAndView roomVotesFrame(HttpSession session, @RequestParam("id") Long roomId){
    ModelAndView mav = new ModelAndView();
    mav.setViewName("roomVotesFrame");
    User user = (User)session.getAttribute("user");
    Room room = rooms.getRoomById(roomId);
    Subscription subscription = subscriptions.getSubscription(user, room);
    mav.addObject("subscription", subscription);
    mav.addObject("question", subscription.getQuestion());
    String summaries = new String("[0, 0], ");
    String votes = new String("[0, 0], ");
    int i=1;
    int vote = 0;
    for(Round r : room.getRounds()){
      if(r.hasElapsed() && r.getSummary() != null){
        summaries += "[" + i + ", " + r.getSummary().getAnswerValue() + "], ";
        UserRoundResult urr = userRoundResults.getUserRoundResult(r, subscription);
        if(urr != null){
          vote = urr.getRoundAcumulatedPoints();
        }
        votes += "[" + i + ", " + vote + "], ";
        i++;
      }
    }
    if(summaries.length()>0){
      //le saca la coma y el espacio del final
      summaries = summaries.substring(0, summaries.length()-2);
      votes = votes.substring(0, votes.length()-2);
    }
    mav.addObject("summaries", summaries);
    mav.addObject("votes", votes);
    return mav;
  }
  
}
